package com.mm.gateway.route;

import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;

/**
 * @BelongsProject: 6.hm-shop
 * @BelongsPackage: com.hmall.gateway.route
 * @Author : 游在海里的鱼
 * @CreateTime : 2024-05-08  10:46
 * @Version : 1.0
 * @ClassName : TODO
 * @Description : TODO
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DynamicRouteLoader {
    @Value("${mm.route.dataId}")
    private String dataId;
    @Value("${mm.route.group}")
    private String group;
    //nacos配置管理，获取配置和添加监听
    private final NacosConfigManager nacosConfigManager;
    //修改路由
    private final RouteDefinitionWriter writer;
    //缓存路由
    private Set<String> routeIdSet = new HashSet<>();

    @PostConstruct
    public void initRouteConfigListener() throws NacosException {
        String configInfo = nacosConfigManager.getConfigService().getConfigAndSignListener(dataId, group, 5000, new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }

            @Override
            public void receiveConfigInfo(String configInfo) {
                updateConfigInfo(configInfo);
            }
        });
        updateConfigInfo(configInfo);
    }

    /* ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 修改路由
     * @Describe: TODO
     **/
     private void updateConfigInfo(String configInfo) {
        log.info("路由开始修改");
        List<RouteDefinition> routeList = JSONUtil.toList(configInfo,RouteDefinition.class);
        //删除路由
        for(String routeId: routeIdSet){
            writer.delete(Mono.just(routeId)).subscribe();
        }
        routeIdSet.clear();
        for(RouteDefinition routeDefinition: routeList){
            writer.save(Mono.just(routeDefinition)).subscribe();
            routeIdSet.add(routeDefinition.getId());
        }
    }

}
